              <div align="right">
${TARGET="offline"}                <a href="${LDAP_SDK_HOME_URL}" style="font-size: 85%">LDAP SDK Home Page</a>
                <br>
                <a href="${BASE}index.${EXTENSION}" style="font-size: 85%">Product Information</a>
                <br>
                <a href="index.${EXTENSION}" style="font-size: 85%">Getting Started with the LDAP SDK</a>
              </div>

              <h2>Common LDAP SDK Data Structures</h2>

              <p>
                The UnboundID LDAP SDK for Java includes a number of data structures that are
                commonly used when creating and using connections and request and result objects.
                They are briefly outlined in this section.
              </p>

              <p></p>
              <h3>Attribute</h3>

              <p>
                Attributes are the fundamental units for storing information in LDAP.  An
                <tt>Attribute</tt> object has a name and zero or more values, and may also have a
                matching rule which provides information about how the SDK should interact with
                values for that attribute.  Attribute values are typically handled as strings, but
                may also be treated as byte arrays.
              </p>

              <p>
                <tt>Attribute</tt> objects are immutable and contain methods for retrieving the
                attribute name and set of values.
              </p>

              <p></p>
              <h3>Entry</h3>

              <p>
                An entry is a named collection of attributes that generally relate to a given
                object (e.g., a person).  The name is a DN, or distinguished name, which will be
                discussed further below.
              </p>

              <p>
                <tt>Entry</tt> objects are mutable and contain methods for retrieving and setting
                the DN, and for retrieving and altering the set of attributes.  They also provide
                methods for representing the entry in LDIF form, and there is a constructor that
                can be used to create an entry from its LDIF representation.
              </p>

              <p></p>
              <h3>Modification</h3>

              <p>
                A <tt>Modification</tt> describes a change that should be applied to an attribute
                in an entry.  An LDAP modify operation includes one or more modifications.
              </p>

              <p>
                A modification consists of a modification type, an attribute name, and zero or more
                values.  The following modification types are supported (and are defined as
                constants in the <tt>Modification</tt> class):
              </p>

              <ul>
                <li>
                  <b>ADD</b> -- Adds a new attribute to an entry, or adds one or more values to an
                  existing attribute.  At least one attribute value must be provided with the ADD
                  modification type.
                  <br><br>
                </li>

                <li>
                  <b>DELETE</b> -- Deletes an attribute from an entry, or deletes one or more
                  values from the attribute.
                  <br><br>
                </li>

                <li>
                  <b>REPLACE</b> -- Replaces the specified attribute in the entry.  If no values
                  are provided, then the attribute will be removed if it exists.  If a set of
                  values was provided, then it will be used in place of the current values, or
                  added to the entry if the specified attribute does not exist.
                  <br><br>
                </li>

                <li>
                  <b>INCREMENT</b> -- Increments an integer value by a specified amount (it may be
                  negative if the value should be decremented).  Exactly one value must be provided
                  with the INCREMENT modification type.
                  <br><br>
                </li>
              </ul>

              <p>
                <tt>Modification</tt> objects provide methods for retrieving the modification type,
                attribute name and set of values, but do not provide any methods for altering the
                content of the modification.
              </p>

              <p></p>
              <h3>Filter</h3>

              <p>
                Search filters define a set of criteria that may be used to identify a set of
                matching entries, or to determine whether a given entry matches a set of criteria.
                There are ten types of filters that may be used in LDAP:
              </p>

              <ul>
                <li>
                  <b>AND</b> -- Encapsulates zero or more other filters and requires that all of
                  those filters must match the target entry.
                  <br><br>
                </li>

                <li>
                  <b>OR</b> -- Encapsulates zero or more other filters and requires that at least
                  one of those filters must match the target entry.
                  <br><br>
                </li>

                <li>
                  <b>NOT</b> -- Encapsulates exactly one other filter and negates the result of
                  that filter (e.g., if the encapsulated filter matches the target entry, then the
                  NOT filter does not match, and vice versa).
                  <br><br>
                </li>

                <li>
                  <b>EQUALITY</b> -- Requires that a specified attribute value must be contained in
                  the target entry.
                  <br><br>
                </li>

                <li>
                  <b>SUBSTRING</b> -- Requires that the target entry must contain at least one
                  value for the specified attribute which matches a substring assertion.
                  <br><br>
                </li>

                <li>
                  <b>GREATER OR EQUAL</b> -- Requires that the target entry must contain at least
                  one value for the specified attribute which is greater than or equal to the
                  provided value.
                  <br><br>
                </li>

                <li>
                  <b>LESS OR EQUAL</b> -- Requires that the target entry must contain at least one
                  value for the specified attribute which is less than or equal to the provided
                  value.
                  <br><br>
                </li>

                <li>
                  <b>PRESENCE</b> -- Requires that the target entry must contain at least one value
                  for the specified attribute.
                  <br><br>
                </li>

                <li>
                  <b>APPROXIMATE MATCH</b> -- Requires that the target entry must contain at least
                  one value for the specified attribute which approximately matches a given value.
                  <br><br>
                </li>

                <li>
                  <b>EXTENSIBLE MATCH</b> -- Requires that the target entry must contain at least
                  one value for the specified attribute which matches a given value using a
                  specified matching rule.
                  <br><br>
                </li>
              </ul>

              <p>
                Because there are different kinds of filters, and there are different kinds of
                information in each type of filter, the <tt>Filter</tt> class does not contain any
                public constructors but instead it contains a number of static methods for creating
                various types of filters.  It is possible to create filters from their string
                representations, but it is also possible to construct filters from their individual
                components.  For example, the "<tt>createEqualityFilter(String attribute name,
                String assertionValue)</tt>" method can be used to create an equality filter with
                the specified name and value.  Constructing filters in this manner rather than from
                a string representation has a number of benefits, including:
              </p>

              <ul>
                <li>
                  It is faster, since it is not necessary to parse the string representation of the
                  filter in order to extract the elements it contains.
                  <br><br>
                </li>

                <li>
                  It is easier, since the assertion value could potentially contain special
                  characters that need to be escaped in order to include them in the string
                  representation, but this is not needed if the raw value is provided separately.
                  <br><br>
                </li>

                <li>
                  It is safer, since if the assertion value may be based on user input then it is
                  not necessary to worry about sanitizing the data or the possibility of injection
                  attacks.
                  <br><br>
                </li>

                <li>
                  <tt>Filter</tt> objects are immutable and contain methods for getting the filter
                  type and the various elements that may be included in each type of filter.
                  <br><br>
                </li>
              </ul>

              <p></p>
              <h3>DN and RDN</h3>

              <p>
                <tt>DN</tt> objects provide a representation of an entry's distinguished name.  The
                DN of an entry uniquely identifies that entry in the directory and also provides
                information about its location in the directory hierarchy.  A DN is comprised of
                zero or more relative distinguished names (RDNs), and each RDN is comprised of one
                or more name-value pairs.
              </p>

              <p>
                In most cases within the LDAP SDK, it is possible to use the string representations
                of DNs and RDNs, but comparing distinguished names should always be done using
                <tt>DN</tt> objects, and comparing relative distinguished names should always be
                done using <tt>RDN</tt> objects.  These objects will perform the comparisons in a
                more correct manner, ignoring insignificant capitalization and spacing differences,
                and differences in the order of the elements in a multivalued RDN.  In addition,
                <tt>DN</tt> and <tt>RDN</tt> objects provide methods for obtaining normalized
                string representations.  Finally, <tt>DN</tt> objects contain methods for
                retrieving the parent DN and for determining whether DN objects have a hierarchical
                relationship.
              </p>
